home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 1
/
Cream of the Crop 1.iso
/
PROGRAM
/
UUPC11QS.ARJ
/
GENSIG.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-08-23
|
16KB
|
385 lines
/*--------------------------------------------------------------------*/
/* Program: gensig.c 24 July 1991 */
/* Author: Andrew H. Derbyshire */
/* Address: ahd@kew.com */
/* Function: Append a random quote to an electronic */
/* mail signature file */
/* Language: Borland C++ 2.0 (in ANSI C mode) */
/* Arguments: Name of file with fixed text input */
/* Name of file with variable quotes */
/* Name of file to be written */
/*--------------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <io.h>
#include <dir.h>
#include <sys/stat.h>
#include <string.h>
#include <time.h>
#include "timestmp.h"
/*--------------------------------------------------------------------*/
/* Internal function prototypes */
/*--------------------------------------------------------------------*/
static void usage( void );
static long chooseit( struct stat *current_status,
const char *lookaside,
const char *fname );
static long getquote( const char *data);
static void CopyQuote( const char *fname, long where, FILE *stream);
static void CopyFixed( const char *fname, FILE *stream );
/*--------------------------------------------------------------------*/
/* m a i n */
/* */
/* main program */
/*--------------------------------------------------------------------*/
void main( int argc, char **argv)
{
long where;
FILE *stream;
banner( argv );
/*--------------------------------------------------------------------*/
/* Validate the number of arguments */
/*--------------------------------------------------------------------*/
if ( argc != 4 )
usage();
/*--------------------------------------------------------------------*/
/* Determine the number of the quotes available, and then */
/* select one */
/*--------------------------------------------------------------------*/
where = getquote( argv[2] );
/*--------------------------------------------------------------------*/
/* Open up our output file */
/*--------------------------------------------------------------------*/
stream = fopen( argv[3] , "w");
if ( stream == NULL )
{
perror( argv[3] );
exit(1);
}
/*--------------------------------------------------------------------*/
/* Copy the fixed and variable parts of the file */
/*--------------------------------------------------------------------*/
CopyFixed( argv[1], stream );
CopyQuote( argv[2], where, stream );
/*--------------------------------------------------------------------*/
/* Close up and return to caller */
/*--------------------------------------------------------------------*/
fclose( stream );
exit( 0 );
} /* main */
/*--------------------------------------------------------------------*/
/* u s a g e */
/* */
/* Report program usage and then exit */
/*--------------------------------------------------------------------*/
static void usage( void )
{
printf("Usage:\tgensig\taddr-file quote-file output-file\n");
printf("\taddr-file\tFixed portion of signature file\n");
printf("\tquote-file\tFile of quotes, separated by delimiter lines\n");
printf("\toutput-file\tOutput file with fixed portion and single quote\n");
exit( 2 );
} /* usage */
/*--------------------------------------------------------------------*/
/* g e t q u o t e */
/* */
/* Select a quote to process */
/*--------------------------------------------------------------------*/
static long getquote( const char *data)
{
struct stat current_status;
long where;
char lookaside[FILENAME_MAX];
char drive[MAXDRIVE], dir[MAXDIR], file[MAXFILE], ext[MAXEXT];
/*--------------------------------------------------------------------*/
/* Get size and data information on the quotes data file */
/*--------------------------------------------------------------------*/
if(stat((char *) data, ¤t_status ) <0)
{
perror( data ); /* If no data file, panic gracefully */
exit( 3 );
} /* if */
/*--------------------------------------------------------------------*/
/* Build the lookaside file name from the data file name */
/*--------------------------------------------------------------------*/
fnsplit( data, drive, dir, file, ext);
fnmerge( lookaside, drive, dir, file, ".las");
/*--------------------------------------------------------------------*/
/* Now get the location of the quote; if it fails the first */
/* time, then the lookaside buffer is updated and we can try */
/* again */
/*--------------------------------------------------------------------*/
where = chooseit( ¤t_status, lookaside, data );
if (where == -1 )
{
where = chooseit( ¤t_status, lookaside, data );
if ( where == - 1)
{
printf("Unable to create lookaside file \"%s\"!\n",
lookaside );
exit( 4 );
} /* if ( where == - 1) */
} /* if ( where == - 1) */
/*--------------------------------------------------------------------*/
/* Return to caller */
/*--------------------------------------------------------------------*/
return where;
} /* getquote */
/*--------------------------------------------------------------------*/
/* c h o o s e i t */
/* */
/* Returns number of quotes in file */
/*--------------------------------------------------------------------*/
static long chooseit( struct stat *current_status,
const char *lookaside,
const char *fname )
{
FILE *stream;
FILE *data;
long where;
int quotes = 0;
int quote;
char buf[BUFSIZ];
char delimiter[BUFSIZ];
/*--------------------------------------------------------------------*/
/* Open up the lookaside file and determine if it is up to */
/* date. If so, choose an entry and return it. */
/*--------------------------------------------------------------------*/
stream = fopen( lookaside , "rb" );
if ( stream != NULL )
{
struct stat status;
fread( &status, sizeof status, 1, stream);
if ((status.st_size == current_status->st_size) &&
(status.st_mtime == current_status->st_mtime))
{ /* Lookaside file up to date, use it */
if( stat((char *) lookaside, &status ) < 0)
{
perror( lookaside );
exit( 5 );
} /* if */
quotes = (status.st_size - sizeof status) / sizeof where;
/* Determine number of quote pointers
in lookaside file from the file's
length */
randomize(); /* Roll them bones ... */
quote = random( quotes );
/* ... Lucky seven? */
fseek( stream, quote * sizeof where , SEEK_CUR );
/* Step required number of quotes
into the file */
fread( &where, sizeof where, 1, stream);
/* Read offset in data file of quote */
printf("Chose quote %d of %d starting at byte %ld of file %s:\n\n",
quote + 1 , quotes, where, fname);
/* Announce number of quote of the day */
fclose( stream ); /* Done with lookaside file, of course */
return where; /* Return position in file to caller */
} /* if */
else
fclose( stream );
} /* if ( stream != NULL ) */
else
perror( lookaside );
/*--------------------------------------------------------------------*/
/* We have to rewrite the lookaside file */
/*--------------------------------------------------------------------*/
data = fopen( fname, "rt"); /* Open data file to scan */
if ( data == NULL ) /* Did it open? */
{
perror( fname ); /* No --> Error */
exit( 6 );
}
stream = fopen( lookaside , "wb" ); /* Open lookaside file */
if ( stream == NULL ) /* Did it open? */
{
perror( lookaside ); /* No --> Error */
exit( 7 );
}
/*--------------------------------------------------------------------*/
/* Start the new lookaside file with the status of the data */
/* file for later comparisons */
/*--------------------------------------------------------------------*/
fwrite( current_status, sizeof *current_status, 1, stream);
/*--------------------------------------------------------------------*/
/* Get the first line of the file, which will contain the */
/* delimiter line */
/*--------------------------------------------------------------------*/
fgets(delimiter, BUFSIZ, data );
where = ftell( data ); /* Get location of possible first quote */
/*--------------------------------------------------------------------*/
/* Now process the rest of the file */
/*--------------------------------------------------------------------*/
while( fgets(buf, BUFSIZ, data ) != NULL )
{
if ( strcmp( buf, delimiter )) /* Delimiter line? */
{ /* No --> data line */
if ( where != -1L ) /* First line of new quote? */
{ /* Yes --> Write location to lookaside */
quotes ++ ;
fwrite( &where, sizeof where, 1, stream);
where = -1L;
} /* if */
} /* if */
else
where = ftell( data ); /* Delimiter line, remember
location of NEXT line in
file */
} /* while */
/*--------------------------------------------------------------------*/
/* Close up shop and return to caller */
/*--------------------------------------------------------------------*/
fclose( stream );
fclose( data );
if ( quotes == 1 )
{
printf("Invalid data file; first line not a delimiter line!");
exit( 99 );
}
printf("Updated lookaside file %s with %d quotes.\n",
lookaside , quotes);
return -1; /* Inform caller that lookaside
file was updated */
} /* chooseit */
/*--------------------------------------------------------------------*/
/* C o p y F i x e d */
/* */
/* Copy fixed input text (user name and address) to output file */
/*--------------------------------------------------------------------*/
static void CopyFixed( const char *fname, FILE *stream )
{
FILE *input;
char buf[BUFSIZ];
/*--------------------------------------------------------------------*/
/* Open input file for copying */
/*--------------------------------------------------------------------*/
input = fopen( fname, "r");
if ( input == NULL )
{
perror( fname );
exit ( 8 );
}
/*--------------------------------------------------------------------*/
/* Copy the fixed input to the signature file */
/*--------------------------------------------------------------------*/
while( fgets( buf, BUFSIZ, input ) != NULL)
fputs( buf, stream );
/*--------------------------------------------------------------------*/
/* Close up shop and return to caller */
/*--------------------------------------------------------------------*/
fclose( input );
} /* CopyFixed */
/*--------------------------------------------------------------------*/
/* C o p y Q u o t e */
/* */
/* Write a quote to the output file */
/*--------------------------------------------------------------------*/
static void CopyQuote( const char *fname, long where, FILE *stream)
{
FILE *input;
char buf[BUFSIZ];
char delimiter[BUFSIZ];
/*--------------------------------------------------------------------*/
/* Open up the quotes file and get the delimiter line */
/*--------------------------------------------------------------------*/
input = fopen( fname, "r");
if ( input == NULL )
{
perror( fname );
exit ( 9 );
}
fgets(delimiter, BUFSIZ, input );
/*--------------------------------------------------------------------*/
/* Position to the beginning of the actual quote to be processed */
/*--------------------------------------------------------------------*/
fseek( input, where , SEEK_SET );
/*--------------------------------------------------------------------*/
/* Copy the quote to both the signature file and the screen */
/*--------------------------------------------------------------------*/
while( fgets( buf, BUFSIZ, input ) != NULL)
{
if (!strcmp( delimiter, buf )) /* Delimiter line? */
break; /* Yes --> End of quote */
fputs( buf, stream ); /* Copy quote to signature file */
fputs( buf, stdout ); /* Copy quote to screen */
} /* while( fgets( buf, BUFSIZ, input ) != NULL) */
/*--------------------------------------------------------------------*/
/* Close up shop and return to caller */
/*--------------------------------------------------------------------*/
fclose( input );
} /* CopyQuote */